#******************************************************************************
#******************************************************************************

# import numpy as np

import random

import src.hyhetra.pipes.utils as utils

import src.hyhetra.pipes.fic as fic

from src.hyhetra.pipes.classes import StandardisedPipeDatabase

from src.hyhetra.pipes.classes import StandardisedPipe

#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def examples(fluiddb: fic.FluidDatabase, 
             singlepipedb: StandardisedPipeDatabase,
             twinpipedb: StandardisedPipeDatabase):
    
    #**************************************************************************
    
    example_flow_matching_routine(fluiddb, singlepipedb)
    
    example_flow_matching_routine(fluiddb, twinpipedb)
    
    #**************************************************************************

#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

# test specific pressure drop matching routine

def example_flow_matching_routine(waterdb, pipedb):
    
    #
    
    seed_number = 128
    
    # set seed number
    
    random.seed(seed_number)
    
    # specific pressure drop
    
    max_specific_pressure_loss = 50 # Pa/m
    
    # district heating details

    fluid_temperature = 273.15+70 # celsius

    #**************************************************************************

    # specify pipe tuples   
    
    number_pipe_tuples = 15
    
    # get number_pipe_tuples random pipe tuples from the database
    
    list_pipe_tuples = [pipe_tuple 
                        for i, pipe_tuple in enumerate(pipedb.pipe_tuples)
                        if random.randint(0,1)][0:number_pipe_tuples]

    # relative pipe roughness

    list_relative_pipe_roughness = [
        0,
        5e-5,
        5e-4,
        5e-3,
        5e-2
        ]
    
    #**************************************************************************
    
    fluid = fic.Fluid(
        phase='l',
        temperature=fluid_temperature,
        pressure=1e5,
        db=waterdb)
    
    # define the pipes under consideration for task 2
    
    list_dh_pipes = [
        StandardisedPipe(
            #length=pipe_length, 
            pipe_tuple=pipe_tuple,
            e_rel=relative_pipe_roughness,
            db=pipedb)
        for pipe_tuple in list_pipe_tuples
        for relative_pipe_roughness in list_relative_pipe_roughness]
    
    #**************************************************************************
        
    list_friction_factor = []
    
    list_fluid_speed = []
    
    list_reynolds_number = []
    
    temp_fluid_speed, temp_reynolds_number, temp_friction_factor = 0, 0, 0
        
    # for each pipe under consideration
    
    for i, pipe in enumerate(list_dh_pipes):
                                            
        #**************************************************************************
        
        # get an initial solution
        # >> should be valid and as close to the actual solution as possible
        # >> one option is to use explicit methods
        
        if i == 0:
            
            # generate initial solution
            
            # (x0_reynolds_number, 
            #  x0_friction_factor) = (
            #      utils.DarcyFrictionFactorReynoldsNumberForPipe(pipe)
            #      )
                     
            # x0_fluid_speed = core.MeanFluidSpeedFromReynoldsNumber(
            #     pipe.d_int,
            #     x0_reynolds_number,
            #     fluid.kinematic_viscosity)   
                
            x0_fluid_speed = None
            x0_reynolds_number = None
            x0_friction_factor = None
            
        else:
            
            # use previous solution
            
            (x0_fluid_speed,
             x0_reynolds_number,
             x0_friction_factor) = (list_fluid_speed[i-1],
                                    list_reynolds_number[i-1],
                                    list_friction_factor[i-1])
        
        # flow regime
        
        # compute the flow speed that leads to the specified pressure loss
        
        temp_fluid_speed, temp_reynolds_number, temp_friction_factor = (
            utils.find_specific_pressure_loss_matching_flow(
                pipe, 
                fluid, 
                max_specific_pressure_loss,
                tolerance=0.001,
                x0_friction_factor=x0_friction_factor,
                x0_reynolds_number=x0_reynolds_number,
                x0_fluid_speed=x0_fluid_speed)
            )
        
        # store the results
        
        list_fluid_speed.append(temp_fluid_speed)
        
        list_reynolds_number.append(temp_reynolds_number)
        
        list_friction_factor.append(temp_friction_factor)
        
        # continue to next pipe, if any
        
        assert temp_fluid_speed > 0
        
        assert temp_reynolds_number > 0
        
        assert temp_friction_factor > 0

#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************